package org.fastsyncer.manager.health;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.fastsyncer.common.constant.CommonConstant;
import org.fastsyncer.common.entity.Mapping;
import org.fastsyncer.common.entity.MappingTask;
import org.fastsyncer.common.util.ApplicationUtil;
import org.fastsyncer.manager.store.DataCenter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 心跳健康监测
 * @ClassName: HeartBeat 
 * @Description: 心跳健康监测:轮训去检查每个驱动配置的可用性
 * @author: YangPei
 * @date: 2017年8月30日 上午10:52:43
 */
public class HeartBeat extends Thread {

	private static Logger logger = LoggerFactory.getLogger(HeartBeat.class);

	private static HeartBeat instance = new HeartBeat();

	HeartBeat() {
		setName("fastsyncer heartbeat listener thread");
	}

	public static HeartBeat getInstance() {
		return instance;
	}
	
	// 驱动列表可以用性
	private static Map<String, HashMap<String, Object>> DRIVERS = new HashMap<String, HashMap<String, Object>>();
	
	// 驱动健康监测心跳时间
	private static final Long HEARTBEAT_TIME = Long.parseLong(ApplicationUtil.getKey(CommonConstant.MANAGER_HEALTH_HEARTBEAT_TIME));
	
	@Override
	public void run() {
		// 启动驱动可用性监听服务
		logger.info("Start heartbeat listening service...");
		while (true) {
			ConcurrentHashMap<String, Object> data = DataCenter.getInstance().getMappings();
			// 遍历现有驱动列表
			for (Map.Entry<String, Object> object : data.entrySet()) {
				MappingTask task = (MappingTask) object.getValue();
				Mapping sourceMapping = task.getSourceMapping();
				List<Mapping> mappings = task.getMappings();

				// 驱动状态信息
				HashMap<String, Object> t = new HashMap<String, Object>();
				// 检查数据源状态
				t.put(CommonConstant.DRIVER_CONFIG_STATE_SOURCE, HealthMonitor.getInstance().test(sourceMapping));

				// 检查目标源状态
				List<Boolean> tState = new ArrayList<Boolean>();
				for (Mapping mapping : mappings) {
					tState.add(HealthMonitor.getInstance().test(mapping));
					t.put(CommonConstant.DRIVER_CONFIG_STATE_TARGET, tState);
				}
				DRIVERS.put(task.getId(), t);
			}

			// 计算已删除的驱动
			List<String> removeName = new ArrayList<>();
			for (Map.Entry<String, HashMap<String, Object>> driver : DRIVERS.entrySet()) {
				String key = driver.getKey();
				// 检查驱动是否存在，不存在说明驱动已删除
				if (data.get(key) == null) {
					removeName.add(key);
				}
			}
			// 踢出失效的驱动
			for (String key : removeName) {
				DRIVERS.remove(key);
			}

			// 防止连接太频繁
			try {
				Thread.sleep(HEARTBEAT_TIME);
			} catch (InterruptedException e) {
	            logger.error(e.getMessage());
			}
		}
	}
	
	/**
	 * 获取驱动的状态信息，检测是否可用
	 * @Title: getDriver 
	 * @Description: 获取驱动的状态信息，检测是否可用
	 * @param taskName 驱动名称
	 * @return: HashMap<String,Object>
	 */
	public HashMap<String, Object> getDriver(String taskName) {
		return DRIVERS.get(taskName);
	}

}
